<?php

namespace TpAmis\Plugin\TableBuilder;

use TpAmis\Renderers\BaseApi;
use TpAmis\Renderers\BaseRenderer;
use TpAmis\Renderers\Operation;
use TpAmis\Traits\BaseApiTrait;
use TpAmis\Traits\ButtonsTrait;

class TableBuilder extends BaseRenderer
{
    use BaseApiTrait;
    use ButtonsTrait;

    protected array $columns = [];
    protected object $amis;
    protected object $filter;
    protected string $primaryKey = 'id';


    public function __construct()
    {
        $this->amis = amis()->CRUDTable();
        $this->amis->syncLocation(false);
        $this->amis->affixHeader(false);
        $this->amis->filterDefaultVisible(false);
        $this->amis->autoFillHeight(false);
        $this->amis->alwaysShowPagination(true);


        $this->filter = amis()->FormBuilder();
        $this->filter->isFilter(true);
        $this->HeaderButtons();

        $this->setApi($this->BaseApiPost(request()->url()));
        $this->setQuickSaveApi($this->BaseApiPut('modify'));
    }

    public static function make()
    {
        return new self();
    }

    public function amis()
    {
        return $this->amis;
    }

    protected BaseApi $api;
    protected BaseApi $quickSaveApi;
    protected BaseApi $quickSaveItemApi;


    /**
     * @param BaseApi $api
     * @return $this
     */
    public function setApi(BaseApi $api): TableBuilder
    {
        $this->api = $api;
        return $this;
    }

    /**
     * @param BaseApi $quickSaveApi
     * @return $this
     */
    public function setQuickSaveApi(BaseApi $api): TableBuilder
    {
        $this->quickSaveApi = $api;
        return $this;
    }


    /**
     * @param BaseApi $quickSaveItemApi
     * @return $this
     */
    public function setQuickSaveItemApi(BaseApi $api): TableBuilder
    {
        $this->quickSaveItemApi = $api;
        return $this;
    }

    function setFilter($key, $value)
    {
        $this->filter->set($key, $value);
        return $this;
    }

    /**
     * 查询表单设置
     * @param string $name 字段名称
     * @param string $label 字段标签
     * @param string $type 字段类型
     * @param mixed $description 字段描述
     * @param mixed $default 默认值
     * @param array $options 选项
     * @param mixed $attr 属性
     * @return static
     */
    function setSearchItem(string $name = '', string $label = '', string $type = 'text', $description = '', $default = '', array $options = [], array $attr = [])
    {
        if ($type == '') {
            $type = 'text';
        }
        $type = strtolower($type);

        $items = [
            'name' => $name,
            'label' => $label,
            'type' => $type,
            'description' => $description,
            'default' => $default,
            'options' => $options,
        ];
        // $args = array_slice(func_get_args(), 5);
        // dump($items,   $attr);
        $args  = array_merge($items, [$attr]);
        $args = array_values($args);

        $this->filter->addFormItem(...$args);
        return $this;
    }
    function setSearchItems($filterItems = [])
    {
        foreach ($filterItems as $item) {
            //后期增加数组构建搜索表单
            $this->setSearchItem(...$item);
        }
        return $this;
    }

    public function filteredResults(): array
    {

        $this->baseHeaderToolBar();
        $this->filter->api($this->api);
        $filter = json_decode(json_encode($this->filter), true);
        $this->filter->unset('type');
        if (isset($filter['body']) && !empty($filter['body'])) {
            $this->baseHeaderToolBar[] = amis('filter-toggler')->align('right');

            $this->filter->set('panelClassName', 'base-filter');

            $this->filter = $this->filter->amis()->actions([
                amis()->Button()->label('重置')->actionType('clear-and-submit'),
                amis('submit')->label('搜索')->level('primary'),
            ]);

            $this->amis->filter($this->filter);
        }

        $this->amis->api($this->api);

        $this->amis->perPageField($this->perPageField);
        $this->amis->perPage($this->perPage);
        $this->amis->filterTogglable();
        // $this->amis->quickSaveApi($this->quickSaveApi);
        // $this->amis->quickSaveItemApi($this->quickSaveItemApi);
        $this->amis->bulkActions($this->bulkActions);
        $this->amis->perPageAvailable($this->perPageAvailable);
        $this->amis->footerToolbar($this->baseFooterToolBar);
        $this->amis->headerToolbar($this->baseHeaderToolBar);
        $this->amis->columns($this->builderColumn());
        if ($this->footable) {
            $this->amis->footable($this->footable);
        }

        return $this->amis->toArray();
    }
    protected $footable = false;
    /**
     * 列底部展示 (Footable)
     * @param mixed $footable
     * @return static
     */
    public function setFootable($footable = true)
    {
        $this->$footable;
        return $this;
    }

    protected $ImageUrlDomain = [];

    /**
     * 设置图片域名
     * @param mixed $filed
     * @param mixed $domain
     * @return static
     */
    public function setImageUrlDomain($filed, $domain)
    {
        $this->ImageUrlDomain[$filed] = $domain;
        return $this;
    }

    /**
     * 批量设置图片域名
     * @param mixed $fileds
     * @return static
     */
    public function setImageUrlDomainFields($fileds = [])
    {
        foreach ($fileds as $filed => $domain) {
            $this->setImageUrlDomain($filed, $domain);
        }
        return $this;
    }

    private function builderColumn()
    {
        $columns = [];
        foreach ($this->columns as $column) {

            $amisColumn = $this->CheckType($column['type'], $column);
            foreach ($this->orderFields as $field) {
                if ($column['name'] == $field) {
                    $amisColumn->sortable(true);
                }
            }
            // foreach ($column['options'] as $key => $value) {
            //     if (!in_array($key, ['quickEdit'])) {
            //         $amisColumn->set($key, $value);
            //     }
            // }
            if (count($column) > 6) {
                $column = array_slice($column, 6);
                if (isset($column)) {
                    foreach ($column as $key => $value) {
                        $amisColumn->set($key, $value);
                    }
                }
            }
            $columns[] = $amisColumn;
        }

        return $columns;
    }

    private function CheckType($type, $args)
    {
        $Column = amis()->TableColumn($args['name'], $args['label'])->remark($args['remark']);
        $modify = [[$this->primaryKey => '${' . $this->primaryKey . '}']];
        switch ($type) {
            case 'mapping':
            case 'status':
            case 'select':
                if (!isset($args['options']['source'])) {
                    if (is_array($args['default']) && !empty($args['default'])) {
                        $options = $args['default'];
                        if (!isset($options[0])) {
                            $options = array_merge([0 => ''], $options);
                        }
                        if (!isset($options['*'])) {
                            $options = array_merge($options, ['*' => '']);
                        }
                        $Column->type('mapping')->map($options);
                    } else {
                        $Column->type('mapping')->map($args['default']);
                    }
                } else {
                    $Column->type('mapping');
                }
                break;

            case 'select.edit':
                $Column->quickEdit([
                    'type' => 'select',
                    "mode" => "inline",
                    'options' => $args['default'],
                    'saveImmediately' => [
                        'api' => $this->BaseApiPost('modify', $modify, [$args['name'] => '${' . $args['name'] . '}'])
                    ]
                ]);
                break;
            case 'switch':
                $Column->quickEdit([
                    'type' => 'switch',
                    "mode" => "inline",
                    'trueValue' => 1,
                    'falseValue' => 0,
                    'saveImmediately' => [
                        'api' => $this->BaseApiPost('modify', $modify, [$args['name'] => '${' . $args['name'] . '}'])
                    ]
                ]);
                break;
            case 'image':
                $Column->type('image')
                    ->enlargeAble()
                    ->src('${' . $args['name'] . '}')
                    ->width('40px')
                    ->height('40px');
                if (isset($this->ImageUrlDomain[$args['name']])) {
                    $Column->src($this->ImageUrlDomain[$args['name']] . '${' . $args['name'] . '}');
                }
                break;
            case 'avatar':
                $Column->type('avatar')->src('${' . $args['name'] . '}');
                if (isset($this->ImageUrlDomain[$args['name']])) {
                    $Column->src($this->ImageUrlDomain[$args['name']] . '${' . $args['name'] . '}');
                }
                break;
            case 'btn':
                return $this->rowActions();
                break;
            case 'text.edit':
            case 'number.edit':
            case 'password.edit':
                $Column->quickEdit([
                    'type' => 'input-' . str_replace('.edit', '', $type),
                    'saveImmediately' => [
                        'api' => $this->BaseApiPost('modify', $modify, [$args['name'] => '${' . $args['name'] . '}'])
                    ]
                ]);
                break;
            case 'property':
                $Column->type('property')
                    ->source('${' . $args['name'] . '}')
                ;
                break;
            case 'table':
                $Column->type('table')
                    ->source('${' . $args['name'] . '}')
                    ->columns($args['default'])
                ;
                break;
            default:
                $Column->type($type);
        }

        return $Column;
    }

    /**
     * @param string $name
     * @param string $label
     * @param string $type
     * @param string|array $default
     * @param array $options 
     * @param array $attr
     * @return $this
     */
    public function addColumn(string $name = '', string $label = '', string $type = 'text', $remark = '', $default = '', array $options = [], $attr = []): TableBuilder
    {

        if ($type == '') {
            $type = 'text';
        }
        $type = strtolower($type);

        $column = [
            'name' => $name,
            'label' => $label,
            'type' => $type,
            'remark' => $remark,
            'default' => $default,
            'options' => $options,
        ];
        $args  = array_merge($column,  $attr);
        $this->columns[] = $args;
        return $this;
    }


    /**
     * @param array $columns
     * @return $this
     */
    public function addColumns(array $columns = []): TableBuilder
    {
        foreach ($columns as $options) {
            call_user_func_array([$this, 'addColumn'], $options);
        }
        return $this;
    }


    protected array $baseHeaderToolBar = [];

    function setHeader($Actions): TableBuilder
    {
        $this->baseHeaderToolBar[] = $Actions;
        return $this;
    }


    public function setTopExportExcel($label = '导出Excel', $api = null)
    {
        $ExportExcel = amis('export-excel')->align('right')->label($label);
        if ($api !== null) {
            $ExportExcel->api($api);
        }
        $this->baseHeaderToolBar[] = $ExportExcel;

        return $this;
    }

    public function setTopExportCsv($label = '导出CSV', $api = null)
    {
        $ExportCsv = amis('export-csv')->align('right')->label($label);
        if ($api !== null) {
            $ExportCsv->api($api);
        }
        $this->baseHeaderToolBar[] = $ExportCsv;
        return $this;
    }
    /**
     * 基础顶部工具栏
     */
    private function baseHeaderToolBar(): void
    {
        $this->baseHeaderToolBar[] = 'bulkActions';
        $this->baseHeaderToolBar[] = amis('reload')->align('right');
    }


    protected array $baseFooterToolBar = ['switch-per-page', 'statistics', 'pagination'];

    private function setFooter($Actions)
    {
        $this->baseFooterToolBar[] = $Actions;
    }

    protected array $perPageAvailable = [15, 20, 25, 50, 100];
    protected int $perPage = 15;
    public function setPerPage(int $perPage = 15)
    {
        $this->perPage = $perPage;
        return $this;
    }
    protected string $perPageField = 'list_rows';

    protected array $bulkActions = [];

    public function HeaderButtons()
    {
        $this->amis->bulkActions($this->bulkActions);
    }

    public function setHeaderButtons($Actions): TableBuilder
    {
        $this->bulkActions[] = $Actions;
        return $this;
    }

    protected array $rowActions = [];

    /**
     * 操作列
     * @return Operation
     */
    protected function rowActions(): Operation
    {
        return amis()->Operation()->label('操作')->buttons($this->rowActions);
    }

    /**
     * 批量添加右侧按钮
     * @param string|array $buttons
     * @return $this
     */
    public function addRightButtons($buttons = []): TableBuilder
    {
        if (!empty($buttons)) {
            $buttons = is_array($buttons) ? $buttons : explode(',', $buttons);
            foreach ($buttons as $key => $value) {
                if (is_object($value)) {
                    $this->rowActions[] = $value->level('link');
                } elseif (is_numeric($key) && is_string($value)) {
                    $this->addRightButton($value);
                } else {
                    $this->addRightButton($key, ...$value);
                }
            }
        }
        return $this;
    }

    public function addRightButton($type = '', ...$args): TableBuilder
    {
        if (is_array($type)) {
            $args = $type;
            $type = $type['type'];
        }

        switch ($type) {
            // 详情按钮
            case 'detail':
                $this->rowActions[] = $this->detailButton(...$args)->level('link');
                break;
            // 编辑按钮
            case 'editer':
                $this->rowActions[] = $this->rowEditerButton(...$args)->level('link');
                break;
            // 编辑按钮
            case 'edit':
                $this->rowActions[] = $this->rowEditButton(...$args)->level('link');
                break;
            // 编辑按钮
            case 'status':
                $this->rowActions[] = $this->rowStatusButton(...$args)->level('link');
                break;
            // 启用按钮
            case 'enable':
                $this->rowActions[] = $this->rowEnableButton(...$args)->level('link');
                break;
            // 禁用按钮
            case 'disable':
                $this->rowActions[] = $this->rowDisableButton(...$args)->level('link');
                break;
            // 删除按钮(不可恢复)
            case 'delete':
                $this->rowActions[] = $this->rowDeleteButton(...$args)->level('link');
                break;
            // 自定义按钮
            case 'custom':
                $this->rowActions[] = $this->rowCustomButton(...$args)->level('link');
                break;
        }
        return $this;
    }
    public function addTopBulkButton($Actions): TableBuilder
    {
        $this->bulkActions[] = $Actions->level('primary');
        return $this;
    }
    public function addTopBulkButtons($buttons = []): TableBuilder
    {
        if (!empty($buttons)) {
            foreach ($buttons as $value) {
                $this->addTopBulkButton($value);
            }
        }
        return $this;
    }
    /**
     * 批量添加右侧按钮
     * @param string|array $buttons
     * @return $this
     */
    public function addTopButtons($buttons = []): TableBuilder
    {
        if (!empty($buttons)) {
            $buttons = is_array($buttons) ? $buttons : explode(',', $buttons);

            foreach ($buttons as $key => $value) {
                if (is_object($value)) {
                    $this->baseHeaderToolBar[] = $value;
                } elseif (is_numeric($key)) {
                    $this->addTopButton($value);
                } else {
                    $this->addTopButton($key, ...$value);
                }
            }
        }
        return $this;
    }

    public function addTopButton($type = '', ...$args): TableBuilder
    {
        if (is_array($type)) {
            $args = $type;
            $type = $type['type'];
        }

        switch ($type) {
            // 添加按钮
            case 'create':
                $this->baseHeaderToolBar[] = $this->createButton(...$args)->level('success');
                break;
            // 添加按钮
            case 'add':
                $this->baseHeaderToolBar[] = $this->addButton(...$args)->level('success');
                break;
            // 编辑按钮
            case 'status':
                $this->bulkActions[] = $this->statusButton(...$args)->level('primary');
                break;
            // 启用按钮
            case 'enable':
                $this->bulkActions[] = $this->bulkEnableButton(...$args)->level('primary');
                break;

            // 禁用按钮
            case 'disable':
                $this->bulkActions[] = $this->bulkDisableButton(...$args)->level('primary');
                break;

            // 删除按钮(不可恢复)
            case 'delete':
                $this->bulkActions[] = $this->bulkDeleteButton(...$args)->level('danger');
                break;
            // 自定义按钮
            case 'custom':
            default:
                $this->bulkActions[] = $this->customButton(...$args)->level('primary');
                break;
        }
        return $this;
    }

    protected $orderFields = [];
    public function addOrder($fileds)
    {
        if (is_string($fileds)) {
            $fileds = explode(',', $fileds);
        }
        if (!empty($fileds)) {
            $this->orderFields = $fileds;
        }
        return $this;
    }
    public function excel()
    {
        amis()->IFrame()->src('')->events([
            'push_data' => [
                'actions' => [
                    [
                        "actionType" => "dialog",
                        "dialog" => [
                            "title" => "弹框",
                            "body" => 'iframe 传给 amis 的 id 是：${iframeId}' // 在弹框中渲染`"iframe 传给 amis 的 id 是：${iframeId}"`这段模板，即111

                        ]
                    ]
                ],
            ]
        ]);
    }

    public function __call($name, $arguments)
    {
        if (strpos($name, 'set') !== false) {
            $name = str_replace('set', '', $name);
            $name = lcfirst($name);
            $this->amis = $this->amis->set($name, ...$arguments);
        }

        return $this;
    }
}
